#!/usr/bin/env python
# -*- coding: utf-8 -*-
# @Time    : 2021/11/19 14:59
# @Author  : huidong.bai
# @File    : nano_control_api.py
# @Software: PyCharm

import hashlib
import json
import uuid

import requests

# osAccessToken = 'eyJhbGciOiJIUzI1NiIsInR5cCI6IkpXVCJ9.eyJhdWQiOiJvcy5jbGllbnQuMDAwMDAxIiwidWlkIjoxOTI5Mywic3YiOiIyIiwicHJvZHVjdElkIjoiU19QUk9EOF8xNDc3IiwiZXhwIjoxNjM3MzEzOTg3LCJkZXZpY2VJZCI6IlhNS0QwMTExOTZCNjM2NjYifQ.HO-WYKKAlPJePZlBMxxVCnI0uiNRawTVJb25rkysrwg'


# 获取osAccessToken，建议每个7000秒获取一次
def get_token(osClientId, productId):
    url = 'https://api.ximalaya.com/xy-os-console/xy-os-ucenter/test/token'

    # 随便写个uid
    uid = '123456'

    payload = {
        'osClientId': osClientId,
        'deviceId': 'test',
        'uid': uid,
        'osRefreshToken': '',
        'productId': productId,
        'serverVersion': 2
    }
    headers = {'Content-Type': 'application/x-www-form-urlencoded'}
    try:
        response = requests.request("POST", url, headers=headers, data=payload)
        return response.json()['osAccessToken']
    except Exception as e:
        print(f'获取token失败：{e}')


def get_params_str(sn, query, product_id, osAccessToken, speakerVersion, romVersion):
    intent = {"intent": "inverseControlAction",
              "slots":
                  {
                      "value":
                          {
                              "intent": "app_key_text_query",
                              "text": query
                          },
                      "speaker_device_id": sn,
                  },
              "domain": "BizInverseControl",
              }

    params = {"productId": product_id,
              "osAccessToken": osAccessToken,
              "speakerVersion": speakerVersion,
              "sysVersion": "15.0.2",
              "dt": "1634526947",
              "deviceType": "1",
              "sysType": "2",
              "deviceid": "E67FF249-C61C-4984-A5A3-05DF2B3FC220",
              "appVersion": "3.0.10",
              "sn": sn,
              "romVersion": romVersion,
              "osClientId": "os.client.000001"
              }

    session = {
        "sid": str(uuid.uuid1()).replace('-', '')
    }

    json_intent = json.dumps(intent, ensure_ascii=False)
    json_params = json.dumps(params, ensure_ascii=False)
    json_session = json.dumps(session, ensure_ascii=False)

    return "intent=" + json_intent + "&" + "params=" + json_params + "&" + "session=" + json_session


def get_sig(params, product_secret='d368298384954202a915217ba34c28cd'):
    """
    :param params:
    :param product_secret: 默认小雅带屏productSecret
    :return: 请求签名sig
    """
    param_list = params.split('&')
    param_list.sort()
    params_str = '&'.join(param_list)
    params_end = params_str + "&productSecret=" + product_secret

    input_name = hashlib.md5()
    input_name.update(params_end.encode("utf-8"))
    return (input_name.hexdigest()).lower()


def url_handler(query, params):
    """
    RTOSproductSecret：b24783503407c7c6ecd80a11a0bbbc0b
    小雅带屏productSecret：d368298384954202a915217ba34c28cd
    早教机productSecret：f6daf518d2ed4e12944adae7c9816164
    :param query:
    :param params:
    :return:
    """
    osAccessToken = get_token(params.get('osClientId'), params.get('productId'))
    params_list = get_params_str(params.get('sn'), query, params.get('productId'), osAccessToken, params.get('speakerVersion'),
                                 params.get('romVersion')).replace(' ', '')

    print(params_list)
    sig = get_sig(params_list, product_secret=params.get('product_secret'))
    return params.get('url') + "?" + params_list + "&sig=" + sig


# 执行自定义指令
def execute(query, params):
    """
    执行反控指令
    :param query: 执行指令
    :param params: 请求参数
    :return: 请求结果
    """
    url = url_handler(query, params)
    headers = {'Host': 'api.ximalaya.com'}
    response = requests.request("GET", url, headers=headers)
    print(url)
    print(response.text)
    return response.text


if __name__ == '__main__':
    data = {
        'sn': 'XMKD011196B63666',
        'url': 'https://api.ximalaya.com/smart-os-gateway/app/invoke',
        'product_secret': 'f6daf518d2ed4e12944adae7c9816164',
        'osClientId': 'os.client.000001_1477',
        'productId': 'S_PROD8_1477',
        'speakerVersion': '1.6.342',
        'romVersion': '1.6.342',
    }

    execute('播放米小圈第三集', data)
